/**
 * Copyright (C) 2014
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * 
 */
package psn.shan.xml.enhancedvalidator;

import java.io.IOException;
import java.io.InputStream;

import javax.inject.Inject;

import lombok.extern.slf4j.Slf4j;

import org.jdom2.Document;
import org.jdom2.JDOMException;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.ImportResource;

import psn.shan.xml.enhancedvalidator.rules.AbstractRuleSet;
import psn.shan.xml.enhancedvalidator.rules.DynamicValidationException;
import psn.shan.xml.enhancedvalidator.rules.RuleLoaderException;
import psn.shan.xml.enhancedvalidator.rules.RuleSetManager;
import psn.shan.xml.enhancedvalidator.util.XmlUtils;

/**
 * 
 * EnhancedValidator <br />
 * 
 * Driver class for enhanced XML validations
 * 
 * @author Shan
 * 
 */
@Slf4j
@Configuration("EnhancedValidator")
@ImportResource("EnhancedXMLValidator.xml")
public class EnhancedValidator<T extends AbstractRuleSet> {

	// Use the RuleSetManager that can manage Rules for specific type. 
	@Inject
	private RuleSetManager<T> mRulesManager;

	/**
	 * Validates the Input document by performing static XSD and Rules validations
	 */
	public void validate(InputStream aInputXML, InputStream aInputXSD) throws RuleLoaderException, StaticValidationException, DynamicValidationException {
		log.info("Loading input XML and performing static validations ...");		
		Document lInput = parseInput(aInputXML, aInputXSD);
		
		log.info("Performing enhanced validations ... ");
		mRulesManager.applyRules(lInput);
	}
	
	/**
	 * Parses the input document to be validated with XSD validation enabled
	 */
	private Document parseInput(InputStream aInputXML, InputStream aInputXSD) throws StaticValidationException {
		try {
			// Parse the input XML with XSD validation enabled. 
			return XmlUtils.parseXML(aInputXML, aInputXSD);
		} catch (JDOMException | IOException e) {
			throw new StaticValidationException("Error parsing XML with XSD validation.", e);
		}
	}
}
